package com.eascs.banknet.boc.service.ftp;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import com.alibaba.dubbo.config.annotation.Reference;
import com.eascs.app.dao.JdbcSession;
import com.eascs.app.log.Logger;
import com.eascs.app.log.LoggerFactory;
import com.eascs.banknet.boc.service.BOCAbstractService;
import com.eascs.banknet.boc.vo.FtpFileTemplage;
import com.eascs.banknet.common.entity.LoanUserEntity;
import com.eascs.banknet.common.entity.LoanapplyEntity;
import com.eascs.banknet.common.entity.O2oPaymentsPlan;
import com.eascs.banknet.common.entity.RphisEntity;
import com.eascs.banknet.common.entity.RpplanLoopEntity;
import com.eascs.banknet.common.entity.RpplanStaticEntity;
import com.eascs.banknet.common.utils.DateUtil;
import com.eascs.banknet.constant.FileTypeConstants;
import com.eascs.banknet.log.entity.LogEntity;
import com.eascs.common.util.StringUtil;
import com.eascs.web.sso.User;
import com.eascs.workflow.common.entity.sys.SysEmail;
import com.eascs.workflow.common.service.email.SysSendEmailOrMessageService;
import com.eascs.workflow.common.service.sys.SysPermissionService;
import com.eascs.workflow.common.vo.ModelResult;

import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;

/**
 * 中行ftp贷后管理相关文件解析
 * 
 * @author Administrator
 *
 */
@Service("bocFtpParseService")
public class BOCFtpParseService extends BOCAbstractService {
	private static final Logger logger = LoggerFactory.getLogger(BOCFtpParseService.class);

	@Inject
	protected JdbcSession o2oJdbcSession;

	@Reference
	private SysPermissionService sysPermissionService;
	@Reference
	private SysSendEmailOrMessageService sysSendEmailOrMessageService;

	@Override
	public LogEntity initLogData() {
		LogEntity logEntity = new LogEntity();
		logEntity.setBankType(LogEntity.BANK_TYPE_BOC);
		logEntity.setTransType("FTP");
		logEntity.setStartTime(new Date());
		return logEntity;
	}

	@Override
	public Map<String, String> dowork() {
		LogEntity logEntity = new LogEntity();
		logEntity.setBankType(LogEntity.BANK_TYPE_BOC);
		logEntity.setStartTime(new Date());
		try {
			logger.info("开始读取中行贷后文件...");
			// 获取过去三天的贷后文件
			List<String> dateList = DateUtil.getDateList(new Date(), 3);
			// 剩余还款计划循环信息，剩余还款计划静态信息，还款历史
			List<String> typeList = Arrays.asList(FileTypeConstants.BOC_FTPTYPE_RPPLANLOOP, FileTypeConstants.BOC_FTPTYPE_RPPLANSTATIC, FileTypeConstants.BOC_FTPTYPE_REPAYHIS);
			for (String fileType : typeList) {
				FtpFileTemplage fileTemplate = bocUtil.getBocFtpFileTemplate(fileType);
				String remotePath = fileTemplate.getLoadPath();
				for (String date : dateList) {
					String fileName = fileTemplate.getFileType() + "-" + date;
					logger.info("读取并保存贷后文件， remotePath：[{}],fileName:[{}]", remotePath, fileName);
					if (FileTypeConstants.BOC_FTPTYPE_RPPLANSTATIC.equals(fileType)) {
						logEntity.setTransType(fileType);
						logEntity.setTypeName("读取剩余还款计划静态信息");
						readRpplanStatic(remotePath, fileName);
					}
					if (FileTypeConstants.BOC_FTPTYPE_RPPLANLOOP.equals(fileType)) {
						logEntity.setTransType(fileType);
						logEntity.setTypeName("读取剩余还款计划循环信息");
						readRpplanLoop(remotePath, fileName);
					}
					if (FileTypeConstants.BOC_FTPTYPE_REPAYHIS.equals(fileType)) {
						logEntity.setTransType(fileType);
						logEntity.setTypeName("读取还款历史");
						readRphis(remotePath, fileName);
					}
				}
			}
			logger.info("读取中行贷后文件完成");
		} catch (Exception e) {
			logger.error("读取中行贷后文件出现异常,errMsg：[{}]", e.getMessage());
			e.printStackTrace();
			logService.writeLog(logEntity, null, LogEntity.RESULT_TYPE_ERROR, e.getMessage());
		}
		return null;
	}

	private void readRpplanStatic(String remotePath, String fileName) throws Exception {
		LogEntity logEntity = initLogData();
		String encoding = "GBK";
		ByteArrayInputStream inputStream = bocNetService.readFtpFile(bocUtil.getBocFtpInfo(), remotePath, fileName);
		InputStreamReader read = new InputStreamReader(inputStream, encoding);// 考虑到编码格式
		BufferedReader bufferedReader = new BufferedReader(read);
		if (bufferedReader.ready()) { // 判断文件是否存在
			String lineTxt = null;
			while ((lineTxt = bufferedReader.readLine()) != null) {
				String[] str = lineTxt.split("\\|");
				RpplanStaticEntity entity = new RpplanStaticEntity();
				entity.setActno(str[0]);
				entity.setPrdType(str[1]);
				entity.setChildType(str[2]);
				entity.setCurrency(str[3]);
				entity.setPrdDes(str[4]);
				entity.setPayWay(str[5]);
				entity.setUnexpMoney(new BigDecimal(str[6]));
				entity.setTailMoney(new BigDecimal(str[7]));
				entity.setInterest(new BigDecimal(str[8]));
				entity.setLoaddl(Integer.valueOf(str[9]));
				entity.setSendDay(str[10]);
				entity.setRate(new BigDecimal(str[11]));
				entity.setDlunit(str[12]);
				entity.setBeginDay(str[13]);
				entity.setPayPeri(str[14]);
				entity.setPayDay(str[15]);
				entity.setBalance(new BigDecimal(str[16]));
				entity.setUnPayTime(Integer.valueOf(str[17]));
				entity.setFineInt(new BigDecimal(str[18]));
				entity.setUnpayMoney(new BigDecimal(str[19]));
				entity.setDelay(str[20]);
				entity.setShouldPay(new BigDecimal(str[21]));
				entity.setSearchDate(str[22]);
				String bankAccount = entity.getActno();
				logger.info(entity.toString());
				// check还款账号是否属于本系统
				LoanapplyEntity loanapplyEntity = loanapplyDao.getLoanEntityByActno(bankAccount);
				if (loanapplyEntity != null) {
					String sql = "select rls.actno from o2o_rpplan_static rls where rls.actno = ?";
					String result = o2oJdbcSession.findString(sql, bankAccount);
					if (StringUtil.isEmpty(result)) {
						int rw = o2oJdbcSession.insert(entity);
						if (rw > 0) {
							logService.writeLog(logEntity, loanapplyDao.getMainAppno(loanapplyEntity.getLoanapplyNo()), LogEntity.RESULT_TYPE_SUCCESS, null);
						}
					}
				}
			}
		} else {
			logger.error("找不到指定的文件");
		}
		read.close();
	}

	// 银行还款计划列表
	private void readRpplanLoop(String remotePath, String fileName) throws Exception {
		String encoding = "GBK";
		InputStream inputStream = bocNetService.readFtpFile(bocUtil.getBocFtpInfo(), remotePath, fileName);
		InputStreamReader read = new InputStreamReader(inputStream, encoding);// 考虑到编码格式
		BufferedReader bufferedReader = new BufferedReader(read);
		if (bufferedReader.ready()) { // 判断文件是否存在
			// 还款计划，单号，发邮件
			Set<String> loanNoSet = new HashSet<String>();

			String lineTxt = null;
			while ((lineTxt = bufferedReader.readLine()) != null) {
				RpplanLoopEntity entity = new RpplanLoopEntity();
				String[] str = lineTxt.split("\\|");
				entity.setActno(str[0]);
				entity.setTerm(Integer.valueOf(str[1]));
				entity.setPayday(str[2]);
				entity.setDaycount(Integer.valueOf(str[3]));
				entity.setPayperterm(new BigDecimal(str[4]));
				entity.setCapital(new BigDecimal(str[5]));
				entity.setInterest(new BigDecimal(str[6]));
				entity.setBalance(new BigDecimal(str[7]));
				logger.info(entity.toString());
				// check还款账号是否存在对应贷款单
				LoanapplyEntity loanapplyEntity = loanapplyDao.getLoanEntityByActno(entity.getActno());
				if (loanapplyEntity != null) {
					// 插入临时表备份数据
					try {
						String sql = "select rlp.actno from o2o_rpplan_loop rlp where rlp.actno = ? and rlp.term = ?";
						String result = o2oJdbcSession.findString(sql, entity.getActno(), entity.getTerm());
						if (StringUtil.isEmpty(result)) {
							o2oJdbcSession.insert(entity);
						}
					} catch (Exception e) {
						logger.info("还款计划插入临时表备份失败,bank_account:[{}]", entity.getActno());
					}
					try {
						int term = entity.getTerm();// 还款期数
						if (term != 9999) {// 中行返回放款总计,不入还款计划表
							// 插入业务表
							String billCode = loanapplyEntity.getBillCode();
							O2oPaymentsPlan payPlan = loanapplyDao.getO2OPaymentsPlanByBillCodeAndTerms(billCode, term);
							if (payPlan == null) {// 数据不存在入库
								LoanUserEntity mainUser = loanapplyDao.getMainLoanUser(loanapplyEntity.getLoanapplyNo());
								if (mainUser != null) {
									Date payDate = DateUtils.parseDate(entity.getPayday(), "yyyyMMdd");
									java.sql.Date sqlDate = new java.sql.Date(payDate.getTime());
									O2oPaymentsPlan plan = new O2oPaymentsPlan();
									plan.setBillCode(billCode);
									plan.setName(mainUser.getUserFullName());
									plan.setIdNumber(mainUser.getDocumentNo());
									plan.setOpratePsn("system");
									plan.setOprateTime(new Date());

									plan.setPayInterest(entity.getInterest());
									plan.setPayPrincipal(entity.getCapital());
									plan.setPaymentsDate(sqlDate);
									plan.setPeriods(Long.valueOf(entity.getTerm()));
									plan.setResidualPrincipal(entity.getBalance());
									plan.setPayTotal(entity.getPayperterm());

									plan.setDataType(3);
									plan.setIsDel("N");
									plan.setRepaymentStatus("HKZ");
									o2oJdbcSession.insert(plan);
									loanNoSet.add(billCode);
								}
							}
						}
					} catch (Exception e) {
						logger.info("更新还款计划表失败:bank_account:[{}]", entity.getActno());
					}
				}
			}

			// 发邮件通知
			sendMail(loanNoSet);
		} else {
			logger.error("找不到指定的文件");
		}
	}

	private String convertEmailContent(Set<String> loanNoSet) {
		// 通过指定模板名获取FreeMarker模板实例
		try {
			Configuration configuration = new Configuration(Configuration.VERSION_2_3_24);
			configuration.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/email/"));
			Template template = configuration.getTemplate("emailTemplate.ftl");
			StringWriter stringWriter = new StringWriter();
			// FreeMarker通过Map传递动态数据
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("loanNoSet", loanNoSet);
			map.put("nowTime", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
			map.put("nowDate", DateFormatUtils.format(new Date(), "yyyy-MM-dd"));
			template.process(map, stringWriter);
			String htmlText = stringWriter.toString();
			return htmlText;
		} catch (Exception e) {
			logger.error("生成邮件模板失败", e);
		}
		return null;
	}

	// 发送邮件
	private void sendMail(Set<String> loanNoSet) {
		try {
			if (loanNoSet.isEmpty()) {
				logger.info("同步贷后数据发邮件，没有还款计划数据,不发送");
				return;
			}

			// 总部贷后管理
			ModelResult<List<User>> modelResult = sysPermissionService.getUserWithRoleCode("1010");
			if (modelResult.isSuccess() && !loanNoSet.isEmpty()) {
				List<User> userList = modelResult.getModel();
				for (User user : userList) {
					SysEmail email = new SysEmail();
					String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
					String title = date + "中行贷款单还款计划更新数据";
					email.setTitle(title);
					email.setRecipients(user.getEmail());
					String content = convertEmailContent(loanNoSet);
					email.setContent(content);
					logger.info("同步贷后数据发邮件:邮件内容:[{}]", new Object[] { content });
					email.setStatus(0);
					email.setCreateTime(new Date());
					int effectRow = sysSendEmailOrMessageService.insertEmail(email);
					if (effectRow > 0) {
						logger.info("同步贷后数据发邮件:user:[{}],入库成功", new Object[] { user.getCname() });
					} else {
						logger.info("同步贷后数据发邮件:user:[{}],入库失败", new Object[] { user.getCname() });
					}
				}
			}
		} catch (Exception e) {
			logger.error("生成邮件模板失败", e);
		}
	}

	private void readRphis(String remotePath, String fileName) throws Exception {
		LogEntity logEntity = initLogData();
		String encoding = "GBK";
		InputStream inputStream = bocNetService.readFtpFile(bocUtil.getBocFtpInfo(), remotePath, fileName);
		InputStreamReader read = new InputStreamReader(inputStream, encoding);// 考虑到编码格式
		BufferedReader bufferedReader = new BufferedReader(read);
		if (bufferedReader.ready()) { // 判断文件是否存在
			String lineTxt = null;
			while ((lineTxt = bufferedReader.readLine()) != null) {
				RphisEntity entity = new RphisEntity();
				String[] str = lineTxt.split("\\|");
				entity.setActno(str[0]);
				entity.setTermno(str[1]);
				entity.setTrnda(str[2]);
				entity.setJrnlno(str[3]);
				entity.setValda(str[4]);
				entity.setRepno(str[5]);
				entity.setRate(new BigDecimal(str[6]));
				entity.setPrin(new BigDecimal(str[7]));
				entity.setIntr(new BigDecimal(str[8]));
				entity.setPrinFine(new BigDecimal(str[9]));
				entity.setIntrFine(new BigDecimal(str[10]));
				entity.setPrinFineFine(new BigDecimal(str[11]));
				entity.setCreateTime(new Date());
				entity.setFileDate(fileName.split("-")[1]);
				String bankAccount = entity.getActno();
				logger.info(entity.toString());
				// check还款账号是否存在对应贷款单
				// LoanapplyEntity loanapplyEntity =
				// loanapplyDao.getLoanEntityByActno(bankAccount);
				// if (loanapplyEntity != null) {
				String sql = "select ors.actno from o2o_rphis ors where ors.actno = ? and ors.termno = ? and ors.trnda = ? and ors.jrnlno = ?";
				String result = o2oJdbcSession.findString(sql, entity.getActno(), entity.getTermno(), entity.getTrnda(), entity.getJrnlno());
				if (StringUtil.isEmpty(result)) {
					o2oJdbcSession.insert(entity);
					logService.writeLog(logEntity, bankAccount, LogEntity.RESULT_TYPE_SUCCESS, null);
				}
				// }
			}
		} else {
			logger.error("找不到指定的文件");
		}
	}

	public static void main(String[] args) {
		try {
			List<String> payDate = DateUtil.getDateList(new Date(), 3);
			System.out.println(payDate.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
